package org.jeecg.modules.bobo.desform.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.apache.shiro.SecurityUtils;
import org.checkerframework.checker.units.qual.K;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.bobo.common.util.ArithUtils;
import org.jeecg.modules.bobo.desform.api.vo.PieChartItemVo;
import org.jeecg.modules.bobo.desform.api.vo.PieChartVo;
import org.jeecg.modules.bobo.desform.entity.LbDesform;
import org.jeecg.modules.bobo.desform.entity.LbDesformData;
import org.jeecg.modules.bobo.desform.service.ILbDesformDataService;
import org.jeecg.modules.bobo.desform.service.ILbDesformService;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.MapExcelConstants;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecgframework.poi.excel.view.JeecgMapExcelView;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 动态表单
 * @Author: jeecg-boot
 * @Date: 2021-04-09
 * @Version: V1.0
 */
@Api(tags = "动态表单")
@RestController
@RequestMapping("/desform/lbDesform")
@Slf4j
public class LbDesformController extends JeecgController<LbDesform, ILbDesformService> {

    @Autowired
    private ILbDesformService lbDesformService;

    @Autowired
    private ILbDesformDataService lbDesformDataService;


    /*---------------------------------主表处理-begin-------------------------------------*/

    /**
     * 分页列表查询
     *
     * @param lbDesform
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "动态表单-分页列表查询")
    @ApiOperation(value = "动态表单-分页列表查询", notes = "动态表单-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(LbDesform lbDesform,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {
        QueryWrapper<LbDesform> queryWrapper = QueryGenerator.initQueryWrapper(lbDesform, req.getParameterMap());
        Page<LbDesform> page = new Page<LbDesform>(pageNo, pageSize);
        IPage<LbDesform> pageList = lbDesformService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 添加
     *
     * @param lbDesform
     * @return
     */
    @AutoLog(value = "动态表单-添加")
    @ApiOperation(value = "动态表单-添加", notes = "动态表单-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody LbDesform lbDesform) {
        if (lbDesformService.saveLbDesform(lbDesform)) {
            return Result.OK("添加成功！");
        }
        return Result.error("添加失败");
    }

    @AutoLog(value = "动态表单-通过id复制")
    @ApiOperation(value = "动态表单-通过id复制", notes = "动态表单-通过id复制")
    @GetMapping(value = "/copyForm")
    public Result<?> copyForm(@RequestParam(name = "id", required = true) String id) {
        LbDesform byId = lbDesformService.getById(id);
        LbDesform copyForm = new LbDesform();
        BeanUtils.copyProperties(byId, copyForm, "id");
        if (lbDesformService.saveLbDesform(copyForm)) {
            return Result.OK("复制成功！");
        }
        return Result.error("复制失败");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "问卷调查-通过id查询")
    @ApiOperation(value = "问卷调查-通过id查询", notes = "问卷调查-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
        LbDesform lbDesform = lbDesformService.getById(id);
        if (lbDesform == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(lbDesform);
    }


    /**
     * 编辑
     *
     * @param lbDesform
     * @return
     */
    @AutoLog(value = "动态表单-编辑")
    @ApiOperation(value = "动态表单-编辑", notes = "动态表单-编辑")
    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody LbDesform lbDesform) {
        if (lbDesformService.updateLbDesformById(lbDesform)) {
            return Result.OK("编辑成功！");
        }
        return Result.error("编辑失败");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "动态表单-通过id删除")
    @ApiOperation(value = "动态表单-通过id删除", notes = "动态表单-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        lbDesformService.delMain(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "动态表单-批量删除")
    @ApiOperation(value = "动态表单-批量删除", notes = "动态表单-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.lbDesformService.delBatchMain(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 导出
     *
     * @return
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, LbDesform lbDesform) {
        return super.exportXls(request, lbDesform, LbDesform.class, "动态表单");
    }

    /**
     * 导入
     *
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, LbDesform.class);
    }
    /*---------------------------------主表处理-end-------------------------------------*/


    /*--------------------------------子表处理-表单数据-begin----------------------------------------------*/

    /**
     * 通过主表ID查询
     *
     * @return
     */
    @AutoLog(value = "表单数据-通过主表ID查询")
    @ApiOperation(value = "表单数据-通过主表ID查询", notes = "表单数据-通过主表ID查询")
    @GetMapping(value = "/listLbDesformDataByMainId")
    public Result<?> listLbDesformDataByMainId(LbDesformData lbDesformData,
                                               @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                               @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                               HttpServletRequest req) {
        QueryWrapper<LbDesformData> queryWrapper = QueryGenerator.initQueryWrapper(lbDesformData, req.getParameterMap());
        Page<LbDesformData> page = new Page<LbDesformData>(pageNo, pageSize);
        IPage<LbDesformData> pageList = lbDesformDataService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    @ApiOperation(value = "表单数据图表-通过主表ID查询", notes = "表单数据图表-通过主表ID查询")
    @GetMapping(value = "/listLbDesformDataChartByMainId")
    public Result<?> listLbDesformDataChartByMainId(LbDesformData lbDesformData, HttpServletRequest req) {
        List<PieChartVo> linkedHashMapList = new ArrayList<>();
        QueryWrapper<LbDesformData> queryWrapper = QueryGenerator.initQueryWrapper(lbDesformData, req.getParameterMap());
        LbDesform lbDesform = lbDesformService.getById(lbDesformData.getDesformId());
        JSONObject jsonOrdered = JSONObject.parseObject(lbDesform.getDesformDesignJson(), Feature.OrderedField);
        JSONObject formDesc = jsonOrdered.getJSONObject("formDesc");
        JSONArray order = jsonOrdered.getJSONArray("order");
//		LinkedHashMap<String, PieChartVo> linkedHashMap;
        String label;
        JSONObject keyObj;
        JSONArray options;
        JSONObject optionsObject;
        PieChartVo pieChartVo = null;
        PieChartItemVo pieChartItemVo;
        for (String key : order.toJavaList(String.class)) {
            try {
                keyObj = formDesc.getJSONObject(key);
                label = keyObj.getString("label");
                pieChartVo = new PieChartVo();
                pieChartVo.setLabel(label);
                pieChartVo.setData(new ArrayList<>());
                options = keyObj.getJSONArray("options");
                for (int i = 0; i < options.size(); i++) {
                    pieChartItemVo = new PieChartItemVo();
                    optionsObject = options.getJSONObject(i);
                    pieChartItemVo.setItem(optionsObject.getString("text"));
                    pieChartItemVo.setValue(String.valueOf(lbDesformDataService.countByKeyAndDesformId(key, lbDesformData.getDesformId(), optionsObject.getString("value"))));
                    pieChartVo.setTotal(ArithUtils.add(pieChartVo.getTotal(), pieChartItemVo.getValue()));
                    pieChartVo.getData().add(pieChartItemVo);
                }

//			linkedHashMap=new LinkedHashMap<>();
//			linkedHashMap.put(key, pieChartVo);
                linkedHashMapList.add(pieChartVo);
            } catch (Exception e) {
                continue;
            }
        }
        return Result.OK(linkedHashMapList);
    }

    /**
     * 添加
     *
     * @param lbDesformData
     * @return
     */
    @AutoLog(value = "表单数据-添加")
    @ApiOperation(value = "表单数据-添加", notes = "表单数据-添加")
    @PostMapping(value = "/addLbDesformData")
    public Result<?> addLbDesformData(@RequestBody LbDesformData lbDesformData) {
        lbDesformDataService.save(lbDesformData);
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param lbDesformData
     * @return
     */
    @AutoLog(value = "表单数据-编辑")
    @ApiOperation(value = "表单数据-编辑", notes = "表单数据-编辑")
    @PutMapping(value = "/editLbDesformData")
    public Result<?> editLbDesformData(@RequestBody LbDesformData lbDesformData) {
        lbDesformDataService.updateById(lbDesformData);
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "表单数据-通过id删除")
    @ApiOperation(value = "表单数据-通过id删除", notes = "表单数据-通过id删除")
    @DeleteMapping(value = "/deleteLbDesformData")
    public Result<?> deleteLbDesformData(@RequestParam(name = "id", required = true) String id) {
        lbDesformDataService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "表单数据-批量删除")
    @ApiOperation(value = "表单数据-批量删除", notes = "表单数据-批量删除")
    @DeleteMapping(value = "/deleteBatchLbDesformData")
    public Result<?> deleteBatchLbDesformData(@RequestParam(name = "ids", required = true) String ids) {
        this.lbDesformDataService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 导出
     *
     * @return
     */
    @RequestMapping(value = "/exportLbDesformData")
//    public ModelAndView exportLbDesformData(HttpServletRequest request, LbDesformData lbDesformData) {
//        // Step.1 组装查询条件
//        QueryWrapper<LbDesformData> queryWrapper = QueryGenerator.initQueryWrapper(lbDesformData, request.getParameterMap());
//        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//
//        // Step.2 获取导出数据
//        List<LbDesformData> pageList = lbDesformDataService.list(queryWrapper);
//        List<LbDesformData> exportList = null;
//
//        // 过滤选中数据
//        String selections = request.getParameter("selections");
//        if (oConvertUtils.isNotEmpty(selections)) {
//            List<String> selectionList = Arrays.asList(selections.split(","));
//            exportList = pageList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
//        } else {
//            exportList = pageList;
//        }
//
//        // Step.3 AutoPoi 导出Excel
//        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
//        mv.addObject(NormalExcelConstants.FILE_NAME, "表单数据"); //此处设置的filename无效 ,前端会重更新设置一下
//        mv.addObject(NormalExcelConstants.CLASS, LbDesformData.class);
//        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("表单数据报表", "导出人:" + sysUser.getRealname(), "表单数据"));
//        mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
//        return mv;
//    }

    public ModelAndView exportLbDesformData(HttpServletRequest request, LbDesformData lbDesformData) {
        // Step.1 组装查询条件
        QueryWrapper<LbDesformData> queryWrapper = QueryGenerator.initQueryWrapper(lbDesformData, request.getParameterMap());
        LbDesform lbDesform = lbDesformService.getById(lbDesformData.getDesformId());
        JSONObject jsonOrdered = JSONObject.parseObject(lbDesform.getDesformDesignJson(), Feature.OrderedField);
        JSONObject formDesc = jsonOrdered.getJSONObject("formDesc");
        JSONArray order = jsonOrdered.getJSONArray("order");
//		LinkedHashMap<String, PieChartVo> linkedHashMap;
        String label;
        JSONObject keyObj;
        JSONArray options;
        JSONObject optionsObject;
        List<LinkedHashMap<String,String>> linkedHashMapList = new ArrayList<>();
        LinkedHashMap<String,String> map;
        for (String key : order.toJavaList(String.class)) {
            try {
                keyObj = formDesc.getJSONObject(key);
                label = keyObj.getString("label");
                map=new LinkedHashMap<>();
                map.put("label",label);
                options = keyObj.getJSONArray("options");
                for (int i = 0; i < options.size(); i++) {
                    optionsObject = options.getJSONObject(i);
                    map.put(optionsObject.getString("text").substring(0,1),String.valueOf(lbDesformDataService.countByKeyAndDesformId(key, lbDesformData.getDesformId(), optionsObject.getString("value"))));
                }
                linkedHashMapList.add(map);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        // Step.3 AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new JeecgMapExcelView());
        //此处设置的filename无效 ,前端会重更新设置一下
        mv.addObject(NormalExcelConstants.FILE_NAME, "问卷统计");
        //注解对象Class
//        mv.addObject(NormalExcelConstants.CLASS,LinkedHashMap.class);
//        mv.addObject(NormalExcelConstants.EXPORT_FIELDS,"label,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z");
        // 设置表头样式
        List<ExcelExportEntity> filedsList = new ArrayList<>();
        filedsList.add(new ExcelExportEntity("问题名称", "label"));
        filedsList.add(new ExcelExportEntity("A", "A"));
        filedsList.add(new ExcelExportEntity("B", "B"));
        filedsList.add(new ExcelExportEntity("C","C"));
        filedsList.add(new ExcelExportEntity("D","D"));
        filedsList.add(new ExcelExportEntity("E","E"));
        filedsList.add(new ExcelExportEntity("F","F"));
        filedsList.add(new ExcelExportEntity("G","G"));
        filedsList.add(new ExcelExportEntity("H","H"));
        filedsList.add(new ExcelExportEntity("I","I"));
        filedsList.add(new ExcelExportEntity("J","J"));
        filedsList.add(new ExcelExportEntity("K","K"));
        filedsList.add(new ExcelExportEntity("L","L"));
        filedsList.add(new ExcelExportEntity("M","M"));
        filedsList.add(new ExcelExportEntity("N","N"));
        filedsList.add(new ExcelExportEntity("O","O"));
        filedsList.add(new ExcelExportEntity("P","P"));
        filedsList.add(new ExcelExportEntity("Q","Q"));
        filedsList.add(new ExcelExportEntity("R","R"));
        filedsList.add(new ExcelExportEntity("S","S"));
        filedsList.add(new ExcelExportEntity("T","T"));
        filedsList.add(new ExcelExportEntity("U","U"));
        filedsList.add(new ExcelExportEntity("V","V"));
        filedsList.add(new ExcelExportEntity("W","W"));
        filedsList.add(new ExcelExportEntity("X","X"));
        filedsList.add(new ExcelExportEntity("Y","Y"));
        filedsList.add(new ExcelExportEntity("Z","Z"));

        mv.addObject(MapExcelConstants.ENTITY_LIST, filedsList);
        
        //自定义表格参数
        mv.addObject(NormalExcelConstants.PARAMS,new ExportParams("问卷调查", "Sheet1"));
//        mv.addObject(NormalExcelConstants.DATA_LIST, linkedHashMapList);
        mv.addObject(NormalExcelConstants.MAP_LIST, linkedHashMapList);
        return mv;
    }

    /**
     * 导入
     *
     * @return
     */
    @RequestMapping(value = "/importLbDesformData/{mainId}")
    public Result<?> importLbDesformData(HttpServletRequest request, HttpServletResponse response, @PathVariable("mainId") String mainId) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            MultipartFile file = entity.getValue();// 获取上传文件对象
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setNeedSave(true);
            try {
                List<LbDesformData> list = ExcelImportUtil.importExcel(file.getInputStream(), LbDesformData.class, params);
                for (LbDesformData temp : list) {
                    temp.setDesformId(mainId);
                }
                long start = System.currentTimeMillis();
                lbDesformDataService.saveBatch(list);
                log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
                return Result.OK("文件导入成功！数据行数：" + list.size());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return Result.error("文件导入失败:" + e.getMessage());
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return Result.error("文件导入失败！");
    }

    /*--------------------------------子表处理-表单数据-end----------------------------------------------*/


}
